package com.pocket.insight.entity;

import com.pocket.insight.base.utils.SerializationUtils;
import lombok.Data;
import org.springframework.boot.configurationprocessor.json.JSONObject;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.pocket.insight.base.utils.SerializationUtils.*;

/**
 * 描述：
 *
 * @author shuize
 * @create 2024/11/29
 */
@Data
public class DatasetField {


    private Long             appId;
    private Long             extendAppId;
    private Long             id;
    private Long             datasetId;
    private String           fieldName;
    private JSONObject       tags;
    private PurposeEnum      purpose;
    private Options          options          = new Options();
    private GeneratedOptions generatedOptions = new GeneratedOptions();


    public DatasetField partialDeepCopy() {
        try {
            DatasetField copy = (DatasetField)clone();
            if (this.options != null) {
                copy.setOptions(this.options.partialDeepCopy());
            }
            if (this.generatedOptions != null) {
                copy.setGeneratedOptions(this.generatedOptions.partialDeepCopy());
            }
            copy.setTags(SerializationUtils.deepCopy(this.tags));
            return copy;
        } catch (CloneNotSupportedException cloneNotSupportedException) {
            return SerializationUtils.deepCopy(this);
        }
    }

    public static <T extends DatasetField> List<T> partialDeepCopyList(List<T> list) {
        List<T> ret = new ArrayList<>();
        if (list != null) {
            for (DatasetField datasetField : list) {
                if (datasetField == null) {
                    ret.add(null); continue;
                }
                ret.add((T)datasetField.partialDeepCopy());
            }
        }
        return ret;
    }

    @Data
    public static class Options implements Cloneable {
        private String              label;
        private String              userComment;
        private String              dbFieldName;
        private Boolean             visible = true;
        private Type.TypeName       type;
        private ME                  expr;
        private Type.TypeConfig     config  = new Type.TypeConfig();
        private Map<String, String> userAddedGeoMap;

        public void setType(Type.TypeName type) {
            this.type = type;
            if (this.expr != null) {
                this.expr.setType(type);
            }
        }

        public Options partialDeepCopy() {
            try {
                Options copy = (Options) this.clone();
                copy.setConfig(deepCopy(this.config));
                copy.setExpr(deepCopy(this.expr));
                if (this.userAddedGeoMap != null) {
                    copy.setUserAddedGeoMap(new HashMap(this.userAddedGeoMap));
                }
                return copy;
            } catch (CloneNotSupportedException var2) {
                return deepCopy(this);
            }
        }

        public void setUserAddedGeoMap(Map<String, String> userAddedGeoMap) {
            this.userAddedGeoMap = userAddedGeoMap;
        }
    }



    @Data
    public static class GeneratedOptions implements Cloneable {
        private String               nativeType;
        private Type.TypeName        originType;
        private Type.TypeName        specialRealType;
        private Type.TypeName        detectedType;
        private String               originName;
        private String               originLabel;
        private String               comment;
        private Integer              sqlType;
        private int                  precision;
        private int                  scale;
        private ME                   expr;
        private Boolean              isReal;
        private List<String>         restrictFunctions;
        private Map<String, String>  userAddedGeoMap;
        private Type.TypeConfig      config         = new Type.TypeConfig();
        private List<Type.FieldType> suggestedTypes = new ArrayList<>();

        public GeneratedOptions partialDeepCopy() {
            try {
                GeneratedOptions copy = (GeneratedOptions) clone();
                copy.setSuggestedTypes(SerializationUtils.deepCopyArray(this.suggestedTypes, Type.FieldType.class));
                if (getRestrictFunctions() != null) {
                    copy.setRestrictFunctions(new ArrayList<>(getRestrictFunctions()));
                }
                return copy;
            } catch (CloneNotSupportedException cloneNotSupportedException) {
                return SerializationUtils.deepCopy(this);
            }
        }
    }


    public enum PurposeEnum {
        MEASURE,
        DIMENSION;
    }
}
